package com.itheima.demo05stream;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

public class Demo07Parallel {
    private static final int times = 500000000;
    long start;

    @Before
    public void inti() {
        start = System.currentTimeMillis();
    }

    @After
    public void destory() {
        long end = System.currentTimeMillis();
        System.out.println("消耗时间: " + (end - start));
    }

    //parallelStream线程安全问题
    @Test
    public void parallelStreamNotice() {
        ArrayList<Integer> list = new ArrayList<>();
        /*IntStream.rangeClosed(1, 1000).
                parallel().
                forEach(i -> list.add(i));
        System.out.println("list.size() = " + list.size());*/

        //使用锁
        /*Object obj = new Object();
        IntStream.rangeClosed(1, 1000)
                .parallel()
                .forEach(i -> {
                    synchronized (obj){
                        list.add(i);
                    }
                });
        System.out.println("list.size() = " + list.size());*/

        //使用线程安全的集合
     /*   Vector<Integer> v = new Vector<>();
        IntStream.rangeClosed(1, 1000).parallel().forEach(
                i -> v.add(i)
        );
        System.out.println("list = " + v.size());*/

        //解决线程安全方案3:调用Stream流的collect/toArray
        List<Integer> collect = IntStream.rangeClosed(1, 1000)
                .parallel()
                .boxed()
                .collect(Collectors.toList());
        System.out.println("collect.size = " + collect.size());
        System.out.println("collect = " + collect);


    }

    //串行的Stream
    @Test
    public void testStream() {
        //得到5亿个数字，并求和
        long reduce = LongStream.rangeClosed(0, times).reduce(0, Long::sum);
        System.out.println("reduce = " + reduce);
    }

    //使用for循环
    @Test
    public void testFor() {
        int sum = 0;
        for (int i = 0; i < times; i++) {
            sum += i;
        }
    }

    @Test
    public void testGetParallelStream() {
        //掌握并行流的两种方式
        //方式1：直接获取并行的Stream流
        ArrayList<String> list = new ArrayList<>();
        Stream<String> stream = list.parallelStream();
        //方式2：将串行流转换成并行流
        Stream<String> parallel = list.stream().parallel();
    }

    @Test
    public void testParallel() {
        Stream.of(4, 5, 3, 9, 1, 2, 6).parallel()
                .filter(s -> {
                    System.out.println(Thread.currentThread() + "::" + s);
                    return s > 3;
                }).count();
    }


    @Test
    public void test0Serial() {
        Stream.of(4, 5, 3, 9, 1, 2, 6).filter(s -> {
            System.out.println(Thread.currentThread() + "::" + s);
            return s > 3;
        }).count();
    }
}
